using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace CubeWars___Demolition.Services
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Camera : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Matrix view, projection, viewRotation;
        Vector3 position = new Vector3(0, 0, 40);
        float yaw, pitch, roll;

        public Matrix View { get { return this.view; } set {} }

        public Matrix ViewRotation { get { return viewRotation; } set { } }

        public Matrix Projection { get { return this.projection; } set { this.projection = value; } }

        public Vector3 Position 
        { 
            get { return this.position; } 
            set
            {
                this.position = value;
                rebuildView();
            }
        }

        public float Yaw 
        { 
            get { return this.yaw; } 
            set 
            {
                this.yaw = value;
                rebuildViewRotation();
                rebuildView();
            } 
        }

        public float Pitch
        {
            get { return this.pitch; }
            set
            {
                this.pitch = value;
                rebuildViewRotation();
                rebuildView();
            }
        }

        public Camera(Game game)
            : base(game)
        {
            game.Services.AddService(typeof(Camera), this);
            rebuildViewRotation();
            rebuildView();
        }

        protected override void LoadContent()
        {
            projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)GraphicsDevice.Viewport.Width / (float)GraphicsDevice.Viewport.Height, 0.1f, 10000.0f);
            base.LoadContent();
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here

            base.Update(gameTime);
        }

        private void rebuildView()
        {
            view = Matrix.CreateLookAt(position, viewRotation.Forward + position, viewRotation.Up);
        }
        private void rebuildViewRotation()
        {
            viewRotation = Matrix.CreateFromYawPitchRoll(yaw, pitch, roll);
        }
    }
}
